package com.nulldev.util.io;

import java.util.Locale;

import com.nulldev.util.JVM.reflections.Reflections;
import com.nulldev.util.VariableAPI.MathUtil;

public class IOUtilsOS {
	public enum OperatingSystem {
		Windows("Windows"),
		MacOS("Mac OS"),
		Android("Android (Linux)"),
		Linux("GNU/Linux"),
		Solaris("Solaris"),
		BSD("BSD"),
		Other("N/A");

		private final String displayOS;

		private OperatingSystem(final String displayOS) {
			this.displayOS = displayOS;
		}

		@Override
		public String toString() {
			return this.displayOS;
		}
	};

	private static OperatingSystem detectedOS = get();

	public static OperatingSystem get() {
		if (detectedOS == null) {
			if (Reflections.is("android.os.SystemProperties")) {
				return detectedOS = OperatingSystem.Android;
			}
			final String OS = System.getProperty("os.name", "generic").toLowerCase(Locale.ENGLISH);
			if ((OS.indexOf("mac") >= 0) || (OS.indexOf("darwin") >= 0)) {
				return detectedOS = OperatingSystem.MacOS;
			} else if (OS.indexOf("win") >= 0) {
				return detectedOS = OperatingSystem.Windows;
			} else if (OS.indexOf("nux") >= 0) {
				return detectedOS = OperatingSystem.Linux;
			} else if (OS.indexOf("solaris") >= 0 || OS.indexOf("sunos") >= 0) {
				return detectedOS = OperatingSystem.Solaris;
			} else if (OS.indexOf("BSD") >= 0) {
				return detectedOS = OperatingSystem.BSD;
			} else {
				return detectedOS = OperatingSystem.Other;
			}
		} else
			return detectedOS;
	}

	public static boolean isLinux() {
		if (detectedOS == null) {
			detectedOS = get();
		}
		return detectedOS.equals(OperatingSystem.Linux);
	}

	public static enum Windows_Type {
		WINDOWS_11(11.0, "Windows 11"),
		WINDOWS_10(10.0, "Windows 10"),
		WINDOWS_8_1(6.3, "Windows 8.1"),
		WINDOWS_8(6.2, "Windows 8"),
		WINDOWS_7(6.1, "Windows 7"),
		WINDOWS_VISTA(6, "Windows Vista"),
		WINDOWS_XP_P64(5.2, "Windows XP [Professional x64]"), /*
																 * Minimum supported version for nullUtil 3 . x
																 */
		WINDOWS_XP(5.1, "Windows XP"), /* Minimum supported version for nullUtil 2.x */
		WINDOWS_2000(5.0, "Windows 2000"),
		WINDOWS_ME(4.9, "Windows ME"),
		WINDOWS_98(4.10, "Windows 98"),
		WINDOWS_95(4, "Windows 95"),
		WINDOWS_NT_3_51(3.51, "Windows NT 3.51"),
		WINDOWS_NT_3_5(3.5, "Windows NT 3.5"),
		WINDOWS_3_2(3.2, "Windows 3.2"),

		N_A(-1, "N/A");

		private final double ntVer;
		private final String ntString;

		private Windows_Type(final double ntVer, final String ntString) {
			this.ntVer = ntVer;
			this.ntString = ntString;
		}

		@Override
		public String toString() {
			return this.ntString;
		}

		public String getNTString() {
			return this.ntString;
		}

		public double getNT() {
			return this.ntVer;
		}

		public static Windows_Type getType() {
			if (!IOUtilsOS.isWindows()) {
				return N_A;
			}
			final double ntVerI = MathUtil.safeParseDouble(System.getProperty("os.version", "generic"), -1);
			for (final Windows_Type type : values()) {
				if (type.getNT() == ntVerI) {
					return type;
				}
			}
			return N_A;
		}
	}

	public static boolean isWindows() {
		return get() == OperatingSystem.Windows;
	}

	public static boolean isBSD() {
		return get() == OperatingSystem.BSD;
	}

	public static boolean isMacOS() {
		return get() == OperatingSystem.MacOS;
	}

	public static boolean isAndroid() {
		return get() == OperatingSystem.Android;
	}
}
